//
//  Rotate.swift
//  
//
//  Created by bo wang on 2020/10/30.
//  Copyright © 2020 wangbo. All rights reserved.
//

import UIKit

// MARK: - 专门负责旋转屏的工具类
final class Rotate {
    
    // 全局默认值
    static let shouldAutorotate: Bool = true
    static let supportedInterfaceOrientations: UIInterfaceOrientationMask = .portrait
    static let preferredInterfaceOrientationForPresentation: UIInterfaceOrientation = .portrait
    
    private static let shared = Rotate()
    private init() {
        NotificationCenter.default.addObserver(self, selector: #selector(deviceOrientationDidChanged(_:)), name: UIDevice.orientationDidChangeNotification, object: nil)
        UIDevice.current.beginGeneratingDeviceOrientationNotifications()
        Self.isLand = UIDevice.current.orientation.isLandscape
    }

    @objc private func deviceOrientationDidChanged(_ noti: NSNotification) {
        let orientation = UIDevice.current.orientation
        Self.isLand = orientation.isLandscape
        Log.info("设备方向调整为：\(orientation.logInfo)")
    }
    
    static func launch() {
        _ = shared
    }
    
    /// 方向枚举
    enum Orientation {
        
        case portrait
        case portraitUpsideDown
        case landscapeRight
        case landscapeLeft
        case unknown
        
        var mapRawValue: Int {
            switch self {
            case .portrait: return UIInterfaceOrientation.portrait.rawValue
            case .portraitUpsideDown: return UIInterfaceOrientation.portraitUpsideDown.rawValue
            case .landscapeRight: return UIInterfaceOrientation.landscapeRight.rawValue
            case .landscapeLeft: return UIInterfaceOrientation.landscapeLeft.rawValue
            case .unknown: return UIInterfaceOrientation.unknown.rawValue
            }
        }
    }
        
    private let unicodes: [UInt8] = [
        111, // o -> 0
        105, // i -> 1
        101, // e -> 2
        116, // t -> 3
        114, // r -> 4
        110, // n -> 5
        97  // a -> 6
    ]
        
    private lazy var key: String = {
        return [
            self.unicodes[0], // o
            self.unicodes[4], // r
            self.unicodes[1], // i
            self.unicodes[2], // e
            self.unicodes[5], // n
            self.unicodes[3], // t
            self.unicodes[6], // a
            self.unicodes[3], // t
            self.unicodes[1], // i
            self.unicodes[0], // o
            self.unicodes[5]  // n
        ].map {
            return String(Character(Unicode.Scalar($0)))
        }.joined()
    }()
        
    /// 旋转到指定方向
    ///
    /// - Parameter orientation: 方向枚举
    private func rotate(to orientation: Orientation) {
        UIDevice.current.setValue(Orientation.unknown.mapRawValue, forKey: key) // 👈 需要先设置成 unknown 哟
        UIDevice.current.setValue(orientation.mapRawValue, forKey: key)
    }
    
    static func toPortrait(_ orientation: Orientation = .portrait) {
        to(orientation)
    }
    
    static func toLandscape(_ orientation: Orientation = .landscapeRight) {
        to(orientation)
    }
    
    static func to(_ orientation: Orientation) {
        shared.rotate(to: orientation)
    }
    
    private(set) static var isLand = false
    static func toggle() {
        isLand.toggle()
        if isLand {
            to(.landscapeLeft)
        } else {
            to(.portrait)
        }
    }
}

extension UIInterfaceOrientationMask {
    var logInfo: String {
        var options = [String]()
        if contains(.portrait) {
            options.append("portrait")
        }
        if contains(.landscapeLeft) {
            options.append("landscapeLeft")
        }
        if contains(.landscapeRight) {
            options.append("landscapeRight")
        }
        if contains(.portraitUpsideDown) {
            options.append("portraitUpsideDown")
        }
        return options.joined(separator: ", ")
    }
}

extension UIInterfaceOrientation {
    var logInfo: String {
        switch self {
        case .unknown: return "unknown"
        case .portrait: return "portrait"
        case .portraitUpsideDown: return "portraitUpsideDown"
        case .landscapeLeft: return "landscapeLeft"
        case .landscapeRight: return "landscapeRight"
        @unknown default: return ""
        }
    }
}

extension UIDeviceOrientation {
    var logInfo: String {
        switch self {
        case .unknown: return "unknown"
        case .portrait: return "portrait"
        case .portraitUpsideDown: return "portraitUpsideDown"
        case .landscapeLeft: return "landscapeLeft"
        case .landscapeRight: return "landscapeRight"
        case .faceUp: return "faceUp"
        case .faceDown: return "faceDown"
        default: return ""
        }
    }
}
